﻿using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

/// <summary>
/// 拉扯方块系统 - 创建一个具有引力场效果的危险区域
/// 当玩家进入范围时会被拉扯向中心，同时受到持续伤害
/// 具有分层的拉扯力和伤害系统，越靠近中心越危险
/// </summary>
public class pullcube : UdonSharpBehaviour
{
    // ================================ 拉扯力设置 ================================
    [Header("拉扯设置")]
    [Tooltip("拉扯影响范围 - 玩家在此范围内会受到拉扯效果（米）")]
    [SerializeField] private float 拉扯范围 = 10f;
    
    [Tooltip("外围拉扯力 - 距离中心较远时的拉扯强度，通常可以轻易逃脱")]
    [SerializeField] private float 外围拉扯力 = 0.05f;
    
    [Tooltip("中间拉扯力 - 距离中心中等时的拉扯强度，逃脱困难")]
    [SerializeField] private float 中间拉扯力 = 0.5f;
    
    [Tooltip("内围拉扯力 - 距离中心很近时的拉扯强度，极难逃脱")]
    [SerializeField] private float 内围拉扯力 = 2f;
    
    [Tooltip("中间区域边界 - 中间拉扯力生效的距离边界（米）")]
    [SerializeField] private float 中间区域边界 = 6f;
    
    [Tooltip("内围区域边界 - 内围拉扯力生效的距离边界（米）")]
    [SerializeField] private float 内围区域边界 = 2f;
    
    // ================================ 伤害系统设置 ================================
    [Header("伤害设置")]
    [Tooltip("生命值系统引用 - 将场景中的WorldHealth组件拖拽到此处，用于对玩家造成伤害")]
    [SerializeField] private WorldHealth 生命值系统;
    
    [Tooltip("外围伤害值 - 在外围区域每秒造成的伤害量")]
    [SerializeField] private float 外围伤害 = 1f;
    
    [Tooltip("中间伤害值 - 在中间区域每秒造成的伤害量")]
    [SerializeField] private float 中间伤害 = 3f;
    
    [Tooltip("内围伤害值 - 在内围区域每秒造成的伤害量")]
    [SerializeField] private float 内围伤害 = 8f;
    
    // 重要说明：伤害系统采用每帧累积计算，确保伤害的精确性和平滑性
    
    // ================================ 调试和测试设置 ================================
    [Header("调试")]
    [Tooltip("显示范围可视化 - 在Scene视图中显示拉扯范围的线框球体")]
    [SerializeField] private bool 显示范围 = true;
    
    [Tooltip("启用伤害功能 - 是否对进入范围的玩家造成伤害")]
    [SerializeField] private bool 启用伤害 = true;
    
    [Tooltip("启用调试信息 - 是否在控制台输出详细的调试信息")]
    [SerializeField] private bool 启用调试信息 = true;
    
    // ================================ 内部状态变量 ================================
    private VRCPlayerApi 玩家API; // 本地玩家API引用
    private bool 玩家在范围内 = false; // 玩家是否在拉扯范围内
    private float 累积伤害 = 0f; // 累积的小数伤害值，用于精确计算
    
    void Start()
    {
        // 获取玩家引用喵~
        玩家API = Networking.LocalPlayer;
        
        // 验证生命值系统引用喵~
        if (生命值系统 == null && 启用伤害)
        {
            Debug.LogWarning("[PullCube] 生命值系统未分配，伤害功能将被禁用喵~");
            启用伤害 = false;
        }
    }
    
    void Update()
    {
        if (玩家API == null) return;
        
        // 检查玩家是否死亡喵~
        if (启用伤害 && 生命值系统 != null && 生命值系统.IsPlayerDead())
        {
            // 玩家死亡时停止拉扯效果喵~
            return;
        }
        
        // 获取玩家位置喵~
        Vector3 玩家位置 = 玩家API.GetPosition();
        Vector3 物体位置 = transform.position;
        
        // 计算距离喵~
        float 距离 = Vector3.Distance(玩家位置, 物体位置);
        
        // 检查是否在范围内喵~
        if (距离 <= 拉扯范围)
        {
            玩家在范围内 = true;
            应用拉扯效果(玩家位置, 物体位置, 距离);
            应用伤害效果(距离);
        }
        else
        {
            玩家在范围内 = false;
        }
    }
    
    /// <summary>
    /// 应用拉扯效果 - 根据距离计算并应用相应的拉扯力
    /// </summary>
    /// <param name="玩家位置">玩家当前位置</param>
    /// <param name="物体位置">拉扯中心位置</param>
    /// <param name="距离">玩家与中心的距离</param>
    void 应用拉扯效果(Vector3 玩家位置, Vector3 物体位置, float 距离)
    {
        // 计算从玩家指向中心的拉扯方向向量
        Vector3 拉扯方向 = (物体位置 - 玩家位置).normalized;
        
        // 只保留水平方向的拉扯力，防止垂直拉扯造成异常效果
        拉扯方向.y = 0f;
        拉扯方向 = 拉扯方向.normalized;
        
        // 根据距离确定拉扯力喵~
        float 拉扯力;
        if (距离 <= 内围区域边界)
        {
            拉扯力 = 内围拉扯力; // 内围：无法逃脱喵~
        }
        else if (距离 <= 中间区域边界)
        {
            拉扯力 = 中间拉扯力; // 中间：逃脱困难喵~
        }
        else
        {
            拉扯力 = 外围拉扯力; // 外围：容易逃脱喵~
        }
        
        // 根据玩家生命值状态调整拉扯力喵~
        if (启用伤害 && 生命值系统 != null)
        {
            if (生命值系统.IsPlayerInDanger())
            {
                // 玩家处于危险状态时，减少拉扯力（让玩家更容易逃脱）喵~
                拉扯力 *= 0.7f;
                if (启用调试信息 && Time.time % 5f < 0.1f)
                {
                    Debug.Log("[PullCube] 玩家处于危险状态，拉扯力减少30%喵~");
                }
            }
            else if (生命值系统.IsPlayerDead())
            {
                // 玩家死亡时，停止拉扯喵~
                return;
            }
        }
        
        // 获取玩家当前速度喵~
        Vector3 当前速度 = 玩家API.GetVelocity();
        
        // 分离水平和垂直速度喵~
        Vector3 垂直速度 = new Vector3(0, 当前速度.y, 0);
        Vector3 玩家水平速度 = new Vector3(当前速度.x, 0, 当前速度.z);
        
        // 计算向中心的拉力喵~
        Vector3 拉力速度 = 拉扯方向 * 拉扯力;
        
        // 将拉力作为额外的移动力添加喵~
        Vector3 新水平速度 = 玩家水平速度 + 拉力速度;
        
        // 合并速度喵~
        Vector3 新速度 = 垂直速度 + 新水平速度;
        
        // 应用新速度喵~
        玩家API.SetVelocity(新速度);
    }
    
    /// <summary>
    /// 应用伤害效果 - 根据距离对玩家造成相应伤害
    /// </summary>
    /// <param name="距离">玩家与中心的距离</param>
    void 应用伤害效果(float 距离)
    {
        // 检查是否启用伤害喵~
        if (!启用伤害 || 生命值系统 == null) return;
        
        // 根据距离确定伤害量喵~
        float 伤害量;
        if (距离 <= 内围区域边界)
        {
            伤害量 = 内围伤害 * Time.deltaTime; // 内围：高伤害喵~
        }
        else if (距离 <= 中间区域边界)
        {
            伤害量 = 中间伤害 * Time.deltaTime; // 中间：中等伤害喵~
        }
        else
        {
            伤害量 = 外围伤害 * Time.deltaTime; // 外围：低伤害喵~
        }
        
        // 累积伤害，避免每帧伤害太小被四舍五入为0喵~
        累积伤害 += 伤害量;
        
        // 当累积伤害达到1或以上时才应用伤害喵~
        if (累积伤害 >= 1f)
        {
            int 实际伤害 = Mathf.RoundToInt(累积伤害);
            生命值系统.RemoveHealth(实际伤害);
            累积伤害 -= 实际伤害; // 减去已应用的伤害，保留小数部分喵~
            
            // 强制更新UI显示喵~
            生命值系统.ForceRefreshAllUI();
            
            // 调试信息喵~
            if (启用调试信息)
            {
                string 区域名称;
                if (距离 <= 内围区域边界)
                {
                    区域名称 = "内围";
                }
                else if (距离 <= 中间区域边界)
                {
                    区域名称 = "中间";
                }
                else
                {
                    区域名称 = "外围";
                }
                
                Debug.Log($"[PullCube] 造成 {实际伤害} 点伤害，距离: {距离:F1}m，区域: {区域名称} 喵~");
            }
        }
    }
    
    /// <summary>
    /// 检查生命值系统状态喵~
    /// </summary>
    public void 检查生命值系统状态()
    {
        if (生命值系统 == null)
        {
            Debug.LogWarning("[PullCube] 生命值系统未分配喵~");
            return;
        }
        
        if (启用调试信息)
        {
            Debug.Log($"[PullCube] 生命值系统状态检查:");
            Debug.Log($"[PullCube] 当前生命值: {生命值系统.GetCurrentHealth()}/{生命值系统.GetMaxHealth()}");
            Debug.Log($"[PullCube] 玩家是否死亡: {生命值系统.IsPlayerDead()}");
            Debug.Log($"[PullCube] 伤害功能启用: {启用伤害}");
        }
    }
    
    /// <summary>
    /// 测试伤害功能喵~
    /// </summary>
    [ContextMenu("测试伤害功能")]
    public void 测试伤害功能()
    {
        if (生命值系统 == null)
        {
            Debug.LogWarning("[PullCube] 生命值系统未分配，无法测试喵~");
            return;
        }
        
        // 模拟造成5点伤害喵~
        生命值系统.RemoveHealth(5);
        Debug.Log("[PullCube] 测试伤害功能：造成5点伤害喵~");
    }
    
    /// <summary>
    /// 显示当前状态信息喵~
    /// </summary>
    [ContextMenu("显示状态信息")]
    public void 显示状态信息()
    {
        if (玩家API == null)
        {
            Debug.LogWarning("[PullCube] 玩家API未初始化喵~");
            return;
        }
        
        Vector3 玩家位置 = 玩家API.GetPosition();
        Vector3 物体位置 = transform.position;
        float 距离 = Vector3.Distance(玩家位置, 物体位置);
        
        Debug.Log($"[PullCube] 当前状态信息:");
        Debug.Log($"[PullCube] 玩家位置: {玩家位置}");
        Debug.Log($"[PullCube] 物体位置: {物体位置}");
        Debug.Log($"[PullCube] 距离: {距离:F2}m");
        Debug.Log($"[PullCube] 拉扯范围: {拉扯范围}m");
        Debug.Log($"[PullCube] 玩家在范围内: {玩家在范围内}");
        Debug.Log($"[PullCube] 伤害功能启用: {启用伤害}");
        
        if (生命值系统 != null)
        {
            Debug.Log($"[PullCube] 生命值系统状态:");
            Debug.Log($"[PullCube] 当前生命值: {生命值系统.GetCurrentHealth()}/{生命值系统.GetMaxHealth()}");
            Debug.Log($"[PullCube] 生命值百分比: {生命值系统.GetHealthPercentage():P1}");
            Debug.Log($"[PullCube] 玩家是否死亡: {生命值系统.IsPlayerDead()}");
            Debug.Log($"[PullCube] 玩家是否危险: {生命值系统.IsPlayerInDanger()}");
        }
        else
        {
            Debug.LogWarning("[PullCube] 生命值系统未分配喵~");
        }
    }
    
    void OnDrawGizmosSelected()
    {
        if (!显示范围) return;
        
        // 绘制拉扯范围喵~
        Gizmos.color = Color.green;
        Gizmos.DrawWireSphere(transform.position, 拉扯范围);
        
        // 绘制中间区域边界喵~
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(transform.position, 中间区域边界);
        
        // 绘制内围区域边界喵~
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, 内围区域边界);
    }
}
